package com.echo.im.engin.handler;

import com.alibaba.fastjson2.JSONObject;
import com.echo.im.client.handler.RecvOfflineHandler;
import com.echo.im.common.enums.MessageType;
import com.echo.im.common.model.ack.MessageACKInfo;
import com.echo.im.client.model.IMMessage;
import com.echo.im.common.model.mq.OfflineMsgMqInfo;
import com.echo.im.common.vo.PrivateMessageVO;
import com.echo.im.engin.packet.out.PrivateMessageOutPacket;
import com.echo.im.infrastructure.mq.event.model.store.OfflineStoreEvent;
import com.echo.im.infrastructure.mq.event.producer.EventPublisher;
import com.echo.im.infrastructure.session.SessionContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * @author: echo
 * @time: 2024-08-25
 */
@Component
@RequiredArgsConstructor
public class RecvOfflineACKHandler implements RecvOfflineHandler {
    private final EventPublisher eventPublisher;
    private final OfflineStoreEvent offlineStoreEvent;

    @Override
    public void handle(Set<Long> offlineUserIdList, IMMessage message) {
        //给所有离线的用户发送ACK,只有私聊才需要
        if(message.getIsNeedOfflineStore()&&message.getData() instanceof PrivateMessageVO){
            offlineUserIdList.forEach(userId-> {
                    //如果为空就证明用户不在线，那么就直接走离线逻辑
                    OfflineMsgMqInfo offlineMsgMqInfo = new OfflineMsgMqInfo(userId,  message.getMsgId(),OfflineMsgMqInfo.OfflineMsgEnum.PRIVATE_OFFLINE_MESSAGE);
                    eventPublisher.publish(offlineStoreEvent,offlineMsgMqInfo);
                    //并伪装 ACK 回传用户
                    if (message.getSeqId()!=null){
                        PrivateMessageOutPacket privateMessageOutPacket = new PrivateMessageOutPacket();
                        privateMessageOutPacket.setSendId(userId);
                        privateMessageOutPacket.setRecvId(message.getSender().getId());
                        privateMessageOutPacket.setType(MessageType.ACK.code());
                        //构造ACK包
                        MessageACKInfo messageACKInfo = new MessageACKInfo();
                        messageACKInfo.setMessageId(message.getMsgId());
                        messageACKInfo.setAckId( message.getSeqId());
                        privateMessageOutPacket.setContent(JSONObject.toJSONString(messageACKInfo));
                        SessionContext.getChannel().writeAndFlush(privateMessageOutPacket);
                }
            });
        }
    }
}
